/*
 * Двудольный граф
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>

#ifdef D
# define debug_fprintf(x) fprintf x
#else
# define debug_fprintf(x) while(0)
#endif

/* {{{ autoarray */
struct vector {
	int *data;
	int n;
	int max;
};

void
vector_init(struct vector *v, int p)
{
	if (p < 0)
		p = 0;
	v->max = 1 << p;
	v->n = 0;
	v->data = (int *) calloc((size_t) v->max, sizeof *v->data);
}

int
vector_append(struct vector *v, int a)
{
	int *t;

	if (v->max == 0)
		vector_init(v, 0);

	if (v->n + 1 > v->max) {
		t = (int *) realloc(v->data, sizeof *t * (v->max *= 2));
		if (!t) {
			fprintf(stderr, "vector_append(): failed to allocate %d bytes\n", v->max);
			return 1;
		} else {
			v->data = t;
		}
	}

	v->data[v->n++] = a;

	return 0;
}

int
vector_sort(struct vector *v, int (*cmpf)(const void *, const void *))
{
	if (v->max > 0 && v->n > 1) {
		qsort(v->data, (size_t) v->n, sizeof *v->data, cmpf);
		return 0;
	} else {
		return 1;
	}
}

int
vector_cleanup(struct vector *v)
{
	if (v->max > 0) {
		v->max = v->n = 0;
		free(v->data);
		v->data = NULL;
		return 0;
	} else {
		return 1;
	}
}
/* }}} */

/* {{{ adjlist w/ vector */
struct adjlist {
	struct vector adj_v;
	bool visited;
	unsigned short color;
};

void
adjl_connect(struct adjlist *node, int conid)
{
#ifdef D2_FPARAM
	fprintf(stderr, "adjl_connect(node=%p = { adj_v = { data=%p, n=%d, max=%d } , s=%d}, conid=%d)\n",
			node, node->adj_v.data, node->adj_v.n, node->adj_v.max, node->s, conid);
#endif
	if (node->adj_v.max == 0)
		vector_init(&node->adj_v, 1);
	vector_append(&node->adj_v, conid);
}

void
adjl_cleanup(struct adjlist *node)
{
	vector_cleanup(&node->adj_v);
}
/* }}} */

int
dfs_chk_bipartite(struct adjlist *al, const int k, const int col)
{
	int i = 0;

	debug_fprintf((stderr, "entering node %2d \t{ visited=%hhd, col=%d }\n",
				k + 1, al[k].visited, al[k].col));
	al[k].visited = true;
	al[k].color = col;
	while (i < al[k].adj_v.n) {
		if (al[al[k].adj_v.data[i]].visited) {
			if (al[al[k].adj_v.data[i]].color == col) {
				debug_fprintf((stderr, "found an odd-length cycle:"
							" discovered when looking from node %d to %d\n",
							k + 1, al[k].adj_v.data[i]));
				return 1;
			}
			i++;
			/* this is the only branch that lets this loop continue */
		} else {
			if (dfs_chk_bipartite(al, al[k].adj_v.data[i], (col == 1 ? 2 : 1)) == 1) {
				return 1;
			}
		}
	}

	return 0;
}

int
main(void)
{
	struct adjlist *al;
	int i, n, m, a, b;

	scanf("%d%d", &n, &m);
	al = (struct adjlist *) calloc(n, sizeof *al);
	for (i = 0; i < m; i++) {
		scanf("%d%d", &a, &b);
		--a; --b;
		adjl_connect(al + a, b);
		adjl_connect(al + b, a);
	}

	for (i = 0; i < n; i++) {
		if (!al[i].visited) {
			if (1 == dfs_chk_bipartite(al, i, 1)) {
				puts("NO");
				goto cleanup;
			}
		}
	}
	puts("YES");

cleanup:
	for (i = 0; i < n; i++)
		adjl_cleanup(al + i);
	free(al);
	return 0;
}
